#
# Tabnotebook Widget
# ----------------------------------------------------------------------
# The Tabnotebook command creates a new window (given by the pathName 
# argument) and makes it into a Tabnotebook widget. Additional options, 
# described above may be specified on the command line or in the option 
# database to configure aspects of the Tabnotebook such as its colors, 
# font, and text. The Tabnotebook command returns its pathName argument. 
# At the time this command is invoked, there must not exist a window 
# named pathName, but pathName's parent must exist.
# 
# A Tabnotebook is a widget that contains a set of tabbed pages. It 
# displays one page from the set as the selected page. A Tab displays 
# the label for the page to which it is attached and serves as a page 
# selector.   When a page's tab is selected, the page's contents are 
# displayed in the page area. The selected tab has a three-dimensional 
# effect to make it appear to float above the other tabs. The tabs are 
# displayed as a group along either the left, top, right, or bottom 
# edge. When first created a Tabnotebook has no pages. Pages may be 
# added or deleted using widget commands described below.
# 
# A special option may be provided to the Tabnotebook. The -auto 
# option specifies whether the Tabnotebook will automatically handle 
# the unpacking and packing of pages when pages are selected. A value 
# of true sig nifies that the notebook will automatically manage it. This 
# is the default value. A value of false signifies the notebook will not 
# perform automatic switching of pages.
# 
# ----------------------------------------------------------------------
#  AUTHOR: Bill W. Scott
#
#  CURRENT MAINTAINER: Chad Smith --> csmith@adc.com or itclguy@yahoo.com
#
#  @(#) $Id: tabnotebook.itk,v 1.7 2002/09/05 20:19:35 smithc Exp $
# ----------------------------------------------------------------------
#            Copyright (c) 1995 DSC Technologies Corporation
# ======================================================================
# Permission to use, copy, modify, distribute and license this software 
# and its documentation for any purpose, and without fee or written 
# agreement with DSC, is hereby granted, provided that the above copyright 
# notice appears in all copies and that both the copyright notice and 
# warranty disclaimer below appear in supporting documentation, and that 
# the names of DSC Technologies Corporation or DSC Communications 
# Corporation not be used in advertising or publicity pertaining to the 
# software without specific, written prior permission.
# 
# DSC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND NON-
# INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE
# AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, 
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. IN NO EVENT SHALL 
# DSC BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 
# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION,
# ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
# SOFTWARE.
# ======================================================================

#
# Default resources.
#
option add *Tabnotebook.borderWidth 2 widgetDefault
option add *Tabnotebook.state normal widgetDefault
option add *Tabnotebook.disabledForeground #a3a3a3 widgetDefault
option add *Tabnotebook.scrollCommand {} widgetDefault
option add *Tabnotebook.equalTabs true widgetDefault
option add *Tabnotebook.font \
	-Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-* widgetDefault
option add *Tabnotebook.width 300 widgetDefault
option add *Tabnotebook.height 150 widgetDefault
option add *Tabnotebook.foreground Black widgetDefault
option add *Tabnotebook.background #d9d9d9 widgetDefault
option add *Tabnotebook.tabForeground Black widgetDefault
option add *Tabnotebook.tabBackground #d9d9d9 widgetDefault
option add *Tabnotebook.backdrop #d9d9d9 widgetDefault
option add *Tabnotebook.margin 4 widgetDefault
option add *Tabnotebook.tabBorders true widgetDefault
option add *Tabnotebook.bevelAmount 0 widgetDefault
option add *Tabnotebook.raiseSelect false widgetDefault
option add *Tabnotebook.auto true widgetDefault
option add *Tabnotebook.start 4 widgetDefault
option add *Tabnotebook.padX 4 widgetDefault
option add *Tabnotebook.padY 4 widgetDefault
option add *Tabnotebook.gap overlap widgetDefault
option add *Tabnotebook.angle 15 widgetDefault
option add *Tabnotebook.tabPos s widgetDefault

#
# Usual options.
#
itk::usual Tabnotebook {
    keep -backdrop -background -borderwidth -cursor -disabledforeground \
	 -font -foreground -tabbackground -tabforeground
}

# ------------------------------------------------------------------
#                            TABNOTEBOOK
# ------------------------------------------------------------------
itcl::class iwidgets::Tabnotebook {
    inherit itk::Widget
    
    constructor {args} {}
    destructor {}
    
    itk_option define -borderwidth borderWidth BorderWidth 2 
    itk_option define -state state State normal
    itk_option define \
	    -disabledforeground disabledForeground DisabledForeground #a3a3a3
    itk_option define -scrollcommand scrollCommand ScrollCommand {}
    itk_option define -equaltabs equalTabs EqualTabs true
    itk_option define -font font Font \
	    -Adobe-Helvetica-Bold-R-Normal--*-120-*-*-*-*-*-*
    itk_option define -width width Width 300
    itk_option define -height height Height 150
    itk_option define -foreground foreground Foreground Black
    itk_option define -background background Background  #d9d9d9
    itk_option define -tabforeground tabForeground TabForeground Black
    itk_option define -tabbackground tabBackground TabBackground #d9d9d9
    itk_option define -backdrop backdrop Backdrop #d9d9d9
    itk_option define -margin margin Margin 4 
    itk_option define -tabborders tabBorders TabBorders true 
    itk_option define -bevelamount bevelAmount BevelAmount 0 
    itk_option define -raiseselect raiseSelect RaiseSelect false 
    itk_option define -auto auto Auto true
    itk_option define -start start Start 4 
    itk_option define -padx padX PadX 4 
    itk_option define -pady padY PadY 4 
    itk_option define -gap gap Gap overlap 
    itk_option define -angle angle Angle 15 
    itk_option define -tabpos tabPos TabPos s 
    
    public method add { args }
    public method configure { args } 
    public method childsite { args }
    public method delete { args } 
    public method index { args } 
    public method insert { index args }
    public method prev { } 
    public method next { }
    public method pageconfigure { index args } 
    public method select { index } 
    public method view { args } 
    
    protected method _reconfigureTabset { } 
    protected method _canvasReconfigure { wid hgt }
    protected method _pageReconfigure { pageName page wid hgt }
    
    private method _getArgs { optList args }
    private method _redrawBorder { wid hgt } 
    private method _recomputeBorder { }
    private method _pack { tabPos } 
    private method _resize {newWidth_ newHeight_}
    
    private variable _canvasWidth 0       ;# currently tabnote canvas width
    private variable _canvasHeight 0      ;# currently tabnote canvas height
    private variable _nbOptList {}        ;# list of notebook options available
    private variable _tsOptList {}        ;# list of tabset options available
    
    private variable _tabPos s            ;# holds -tabPos, because of ordering
    
    private variable _borderRecompute false   ;# did we dirty border after cfg?
    private variable _tabsetReconfigure false ;# did we dirty tabsets after cfg?
    
}


# ----------------------------------------------------------------------
#                              CONSTRUCTOR
# ----------------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::constructor {args} {
    # The following conditional added for SF ticket #514222.   csmith 9/5/02
    if {$::tk_version > 8.3} {
      component hull configure -borderwidth 0 -padx 0 -pady 0
    } else {
      component hull configure -borderwidth 0
    }

    #
    # Create the outermost canvas to maintain geometry.
    #
    itk_component add canvas {
	canvas $itk_interior.canvas -highlightthickness 0
    } {
	keep -cursor -background -width -height
    }
    bind $itk_component(canvas) <Configure> [itcl::code $this _resize %w %h]

    
    
    # .......................
    # Create the NOTEBOOK
    #
    itk_component add notebook {
	iwidgets::Notebook $itk_interior.canvas.notebook 
    } {
	keep -cursor -background 
    }
    
    #
    # Ouch, create a dummy page, go pageconfigure to get its options
    # and munge them into a list for later doling by pageconfigure
    #
    $itk_component(notebook) add
    set nbConfigList [$itk_component(notebook) pageconfigure 0]
    foreach config $nbConfigList {
	lappend _nbOptList [lindex $config 0]
    }
    $itk_component(notebook) delete 0
    
    # 
    # Create the tabset.
    #
    itk_component add tabset {
	iwidgets::Tabset $itk_interior.canvas.tabset \
		-command [itcl::code $this component notebook select]
    } {
	keep -cursor 
    }
    
    eval itk_initialize $args
    
    #
    # Ouch, create a dummy tab, go tabconfigure to get its options
    # and munge them into a list for later doling by pageconfigure
    #
    $itk_component(tabset) add
    set tsConfigList [$itk_component(tabset) tabconfigure 0]
    foreach config $tsConfigList {
	lappend _tsOptList [lindex $config 0]
    }
    $itk_component(tabset) delete 0
    
    bind $itk_component(tabset) <Configure> \
	    [itcl::code $this _reconfigureTabset]
    
    _pack $_tabPos
    $itk_component(hull) configure -width [cget -width] -height [cget -height]
}

proc ::iwidgets::tabnotebook {pathName args} {
    uplevel ::iwidgets::Tabnotebook $pathName $args
}


# -------------------------------------------------------------
# DESTRUCTOR: destroy the Tabnotebook
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::destructor {} {
}

# ----------------------------------------------------------------------
# OPTION -borderwidth
#
# Thickness of Notebook Border
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::borderwidth {
    if {$itk_option(-borderwidth) != {}} {
	#_recomputeBorder
	set _borderRecompute true
    }
}

# ----------------------------------------------------------------------
# OPTION -state
#
# State of the tabs in the tab notebook: normal or disabled
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::state {
    if {$itk_option(-state) != {}} {
	$itk_component(tabset) configure -state $itk_option(-state)
	#_reconfigureTabset
	set _tabsetReconfigure true
	
    }
}

# ----------------------------------------------------------------------
# OPTION -disabledforeground
#
# Specifies a foreground color to use for displaying a 
# tab's label when its state is disabled.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::disabledforeground {
    
    if {$itk_option(-disabledforeground) != {}} {
	$itk_component(tabset) configure \
		-disabledforeground $itk_option(-disabledforeground)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -scrollcommand
#
# Standard option. See options man pages.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::scrollcommand {
    
    if {$itk_option(-scrollcommand) != {}} {
	$itk_component(notebook) \
		configure -scrollcommand $itk_option(-scrollcommand)
    }
}

# ----------------------------------------------------------------------
# OPTION -equaltabs
#
# Specifies whether to force tabs to be equal sized or not. 
# A value of true means constrain tabs to be equal sized. 
# A value of false allows each tab to size based on the text 
# label size. The value may have any of the forms accepted by 
# the Tcl_GetBoolean, such as true, false, 0, 1, yes, or no.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::equaltabs {
    
    if {$itk_option(-equaltabs) != {}} {
	$itk_component(tabset) \
		configure -equaltabs $itk_option(-equaltabs)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -font
#
# Font for tab labels when they are set to text (-label set)
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::font {
    
    if {$itk_option(-font) != {}} {
	$itk_component(tabset) configure -font $itk_option(-font)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -width
#
# Width of the Tabnotebook
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::width {
    if {$itk_option(-width) != {}} {
	$itk_component(canvas) configure -width $itk_option(-width)
	#_recomputeBorder
	set _borderRecompute true
    }
}

# ----------------------------------------------------------------------
# OPTION -height
#
# Height of the Tabnotebook
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::height {
    if {$itk_option(-height) != {}} {
	$itk_component(canvas) configure -height $itk_option(-height)
	#_recomputeBorder
	set _borderRecompute true
    }
}

# ----------------------------------------------------------------------
# OPTION -foreground
#
# Specifies a foreground color to use for displaying a page 
# and its associated tab label (this is the selected state).
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::foreground {
    
    if {$itk_option(-foreground) != {}} {
	$itk_component(tabset) configure \
		-selectforeground $itk_option(-foreground)
    }
}

# ----------------------------------------------------------------------
# OPTION -background
#
# Specifies a background color to use for displaying a page 
# and its associated tab bg (this is the selected state).
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::background {
    
    if {$itk_option(-background) != {}} {
	$itk_component(tabset) configure \
		-selectbackground $itk_option(-background)
	#_recomputeBorder
	set _borderRecompute true
    }
}

# ----------------------------------------------------------------------
# OPTION -tabforeground
#
# Specifies a foreground color to use for displaying tab labels 
# when they are in their unselected state.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::tabforeground {
    
    if {$itk_option(-tabforeground) != {}} {
	$itk_component(tabset) configure \
		-foreground $itk_option(-tabforeground)
    }
}

# ----------------------------------------------------------------------
# OPTION -tabbackground
#
# Specifies a background color to use for displaying tab backgrounds 
# when they are in their unselected state.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::tabbackground {
    
    if {$itk_option(-tabbackground) != {}} {
	$itk_component(tabset) configure \
		-background $itk_option(-tabbackground)
    }
}

# ----------------------------------------------------------------------
# OPTION -backdrop
#
# Specifies a background color to use when filling in the 
# area behind the tabs.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::backdrop {
    
    if {$itk_option(-backdrop) != {}} {
	$itk_component(tabset) configure \
		-backdrop $itk_option(-backdrop)
    }
}

# ----------------------------------------------------------------------
# OPTION -margin
#
# Sets the backdrop margin between tab edge and backdrop edge
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::margin {
    if {$itk_option(-margin) != {}} {
	$itk_component(tabset) configure -margin $itk_option(-margin)
    }
}

# ----------------------------------------------------------------------
# OPTION -tabborders
#
# Boolean that specifies whether to draw the borders of
# the unselected tabs (tabs in background)
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::tabborders {
    if {$itk_option(-tabborders) != {}} {
	$itk_component(tabset) \
		configure -tabborders $itk_option(-tabborders)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -bevelamount
#
# Specifies pixel size of tab corners. 0 means no corners.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::bevelamount {
    if {$itk_option(-bevelamount) != {}} {
	$itk_component(tabset) \
		configure -bevelamount $itk_option(-bevelamount)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -raiseselect
#
# Sets whether to raise selected tabs
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::raiseselect {
    if {$itk_option(-raiseselect) != {}} {
	$itk_component(tabset) \
		configure -raiseselect $itk_option(-raiseselect)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -auto
#
# Determines whether pages are automatically unpacked and
# packed when pages get selected.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::auto {
    if {$itk_option(-auto) != {}} {
	$itk_component(notebook) configure -auto $itk_option(-auto)
    }
}

# ----------------------------------------------------------------------
# OPTION -start
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::start {
    
    if {$itk_option(-start) != {}} {
	$itk_component(tabset) configure \
		-start $itk_option(-start)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -padx
#
# Specifies a non-negative value indicating how much extra space 
# to request for a tab around its label in the X-direction. 
# When computing how large a window it needs, the tab will add 
# this amount to the width it would normally need The tab will 
# end up with extra internal space to the left and right of its 
# text label. This value may have any of the forms acceptable 
# to Tk_GetPixels.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::padx {
    
    if {$itk_option(-padx) != {}} {
	$itk_component(tabset) configure -padx $itk_option(-padx)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -pady
#
# Specifies a non-negative value indicating how much extra space to 
# request for a tab around its label in the Y-direction. When computing 
# how large a window it needs, the tab will add this amount to the 
# height it would normally need The tab will end up with extra internal 
# space to the top and bot tom of its text label. This value may have 
# any of the forms acceptable to Tk_GetPixels.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::pady {
    
    if {$itk_option(-pady) != {}} {
	$itk_component(tabset) configure -pady $itk_option(-pady)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -gap
#
# Specifies the amount of pixel space to place between each tab. 
# Value may be any pixel offset value. In addition, a special keyword 
# 'overlap' can be used as the value to achieve a standard overlap of 
# tabs. This value may have any of the forms acceptable to Tk_GetPixels.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::gap {
    
    if {$itk_option(-gap) != {}} {
	$itk_component(tabset) configure -gap $itk_option(-gap)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -angle
#
# Specifes the angle of slope from the inner edge to the outer edge 
# of the tab. An angle of 0 specifies square tabs. Valid ranges are 
# 0 to 45 degrees inclusive. Default is 15 degrees. If tabPos is 
# e or w, this option is ignored.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::angle {
    
    if {$itk_option(-angle) != {}} {
	$itk_component(tabset) configure -angle $itk_option(-angle)
	#_reconfigureTabset
	set _tabsetReconfigure true
    }
}

# ----------------------------------------------------------------------
# OPTION -tabpos
#
# Specifies the location of the set of tabs in relation to the 
# Notebook area. Must be n, s, e, or w.   Defaults to s.
# ----------------------------------------------------------------------
itcl::configbody iwidgets::Tabnotebook::tabpos {
    
    if {$itk_option(-tabpos) != {}} {
	set _tabPos $itk_option(-tabpos)
	$itk_component(tabset) configure \
		-tabpos $itk_option(-tabpos)
	pack forget $itk_component(canvas)
	pack forget $itk_component(tabset)
	pack forget $itk_component(notebook)
	_pack $_tabPos
    }
}

# -------------------------------------------------------------
# METHOD: configure ?<option>? ?<value> <option> <value>...?
#
# Acts as an addendum to the itk::Widget::configure method.
#
# Checks the _recomputeBorder flag and the _tabsetReconfigure to
# determine what work has been batched to after the configure
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::configure { args } {
    set result [eval itk::Archetype::configure $args]
    
    # check for flags then do update...
    if { $_borderRecompute == "true" } { 
	_recomputeBorder
	set _borderRecompute false
    }
    
    if { $_tabsetReconfigure == "true" } { 
	_reconfigureTabset
	set _tabsetReconfigure false
    }
    
    return $result
    
}

# -------------------------------------------------------------
# METHOD: add ?<option> <value>...?
#
# Creates a page and appends it to the list of pages.
# processes pageconfigure for the page added.
#
# Returns the page's childsite frame
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::add { args } {
    
    # The args list should be an even # of params, if not then
    # prob missing value for last item in args list. Signal error.
    set len [llength $args]
    if { [expr {$len % 2}] } {
	error "value for \"[lindex $args [expr {$len - 1}]]\" missing"
    }
    
    # pick out the notebook args
    set nbArgs [eval _getArgs [list $_nbOptList] $args]
    set pageName [eval $itk_component(notebook) add $nbArgs]
    
    # pick out the tabset args
    set tsArgs [eval _getArgs [list $_tsOptList] $args]
    eval $itk_component(tabset)   add $tsArgs
    
    set page [index end]
    bind $pageName <Configure> \
	    [itcl::code $this _pageReconfigure $pageName $page %w %h]
    return $pageName
}

# -------------------------------------------------------------
# METHOD: childsite ?<index>?
#
# If index is supplied, returns the child site widget 
# corresponding to the page index.  If called with no arguments,
# returns a list of all child sites
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::childsite { args } {
    return [eval $itk_component(notebook) childsite $args]
}

# -------------------------------------------------------------
# METHOD: delete <index1> ?<index2>?
#
# Deletes a page or range of pages from the notebook
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::delete { args } {
    eval $itk_component(notebook) delete $args
    eval $itk_component(tabset)   delete $args
}


# -------------------------------------------------------------
# METHOD: index <index>
#
# Given an index identifier returns the numeric index of the page
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::index { args } {
    return [eval $itk_component(notebook) index $args]
}

# -------------------------------------------------------------
# METHOD: insert <index> ?<option> <value>...?
#
# Inserts a page before a index. The before page may
# be specified as a label or a page position.
#
# Note that since we use eval to preserve the $args list,
# we must use list around $index to keep it together as a unit
#
# Returns the name of the page's child site
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::insert { index args } {
    
    # pick out the notebook args
    set nbArgs [eval _getArgs [list $_nbOptList] $args]
    set pageName [eval $itk_component(notebook) insert [list $index] $nbArgs]
    
    # pick out the tabset args
    set tsArgs [eval _getArgs [list $_tsOptList] $args]
    eval $itk_component(tabset)   insert [list $index] $tsArgs
    
    return $pageName
    
}

# -------------------------------------------------------------
# METHOD: prev
#
# Selects the previous page. Wraps at first back to last page.
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::prev { } {
    eval $itk_component(notebook) prev
    eval $itk_component(tabset)   prev
}

# -------------------------------------------------------------
# METHOD: next
#
# Selects the next page. Wraps at last back to first page.
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::next { } {
    eval $itk_component(notebook) next
    eval $itk_component(tabset)   next
}

# -------------------------------------------------------------
# METHOD: pageconfigure <index> ?<option> <value>...?
#
# Performs configure on a given page denoted by index.
# Index may be a page number or a pattern matching the label
# associated with a page.
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::pageconfigure { index args } {
    
    set nbArgs [eval _getArgs [list $_nbOptList] $args]
    set tsArgs [eval _getArgs [list $_tsOptList] $args]
    
    set len [llength $args]
    switch $len {
	0 {
	    # Here is the case where they just want to query options
	    set nbConfig \
		    [eval $itk_component(notebook) pageconfigure $index $nbArgs]
	    set tsConfig \
		    [eval $itk_component(tabset)   tabconfigure $index $tsArgs]
	    #
	    # BUG: this currently just concatenates a page and a tab's
	    # config lists together... We should bias to the Page
	    # since this is what we are using as primary when both??
	    #
	    # a pageconfigure index -background will return something like:
	    # -background background Background #9D008FF583C1 gray70 \
		    # -background background background white gray 70
	    #
	    return [concat $nbConfig $tsConfig]
	}
	1 {
	    # Here is the case where they are asking for only one
	    # one options value... need to figure out which one
	    # (page or tab) can service this. Then only return
	    # that one's result.
	    
	    if { [llength $nbArgs] != 0 } {
		return [eval $itk_component(notebook) \
			pageconfigure $index $nbArgs]
	    } elseif { [llength $tsArgs] != 0 } {
		return [eval $itk_component(tabset) \
			tabconfigure $index $tsArgs]
	    } else {
		error "unknown option \"$args\""
	    }
	    
	}
	default {
	    
	    # pick out the notebook args
	    set nbConfig \
		    [eval $itk_component(notebook) \
		    pageconfigure [list $index] $nbArgs]
	    
	    # pick out the tabset args
	    set tsConfig \
		    [eval $itk_component(tabset)   \
		    tabconfigure [list $index] $tsArgs]
	    
	    return ""
	    #return [concat $nbConfig $tsConfig]
	    
	}
    }
}

# -------------------------------------------------------------
# METHOD: select index
#
# Select a page by index
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::select { index } {
    $itk_component(notebook) select $index
    $itk_component(tabset)   select $index
}

# -------------------------------------------------------------
# METHOD: view
#
# Return the current page
#
#         view index
#
# Selects the page denoted by index to be current page
#
#	  view 'moveto' fraction
#
# Selects the page by using fraction amount
#
#	  view 'scroll' num what
#
# Selects the page by using num as indicator of next or
# previous
#
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::view { args } {
    eval $itk_component(notebook) view $args
    $itk_component(tabset) select [index select]
}

# -------------------------------------------------------------
# PRIVATE METHOD: _getArgs
#
# Given an optList returned from a configure on an object and
# given a candidate argument list, peruse throught the optList
# and build a new argument list with only those options found
# in optList.
#
# This is used by the add, insert, and pageconfigure methods.
# It is useful for a container kind of class like Tabnotebook
# to be smart about args it gets for its concept of a "page"
# which is actually a Notebook Page and a Tabset Tab.
#
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_getArgs { optList args } {
    
    set len [llength $args]
    
    set retArgs {}
    
    for {set i 0} {$i < $len} {incr i} {
	# get the option for this pair
	set opt [lindex $args $i]
	
	# move ahead to the value
	incr i
	
	# option exists!
	if { [lsearch -exact $optList $opt] != -1} {
	    lappend retArgs $opt
	    if {$i < [llength $args]} {
		lappend retArgs [lindex $args $i]
	    }
	    # option does not exist
	}
    }
    
    return $retArgs
}

# -------------------------------------------------------------
# PROTECTED METHOD: _reconfigureTabset
#
# bound to the tabset reconfigure... We call our canvas 
# reconfigure as if the canvas resized, it then configures
# the tabset correctly.
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_reconfigureTabset { } {
    _canvasReconfigure $_canvasWidth $_canvasHeight
    
}

# -------------------------------------------------------------
# PROTECTED METHOD: _canvasReconfigure
#
# bound to window Reconfigure event of the canvas
# keeps the tabset area stretched in its major dimension.
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_canvasReconfigure { wid hgt } {
    
    if { $_tabPos == "n" || $_tabPos == "s" } {
	$itk_component(tabset) configure -width $wid
    } else {
	$itk_component(tabset) configure -height $hgt
    }
    
    set _canvasWidth $wid
    set _canvasHeight $hgt
    
    _redrawBorder $wid $hgt 
    
}

# -------------------------------------------------------------
# PRIVATE METHOD: _redrawBorder
#
# called by methods when the packing changes, borderwidths, etc.
# and height
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_redrawBorder { wid hgt } {
    
    # Get the top of the Notebook area...
    
    set nbTop [winfo y $itk_component(notebook)]
    set canTop [expr {$nbTop - $itk_option(-borderwidth)}]
    
    $itk_component(canvas) delete BORDER
    if { $itk_option(-borderwidth) > 0 } {
	
	# For south, east, and west -- draw the top/north edge
	if { $_tabPos != "n" } {
	    $itk_component(canvas) create line \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    $wid \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    -width $itk_option(-borderwidth) \
		    -fill [iwidgets::colors::topShadow $itk_option(-background)] \
		    -tags BORDER
	}
	
	# For north, east, and west -- draw the bottom/south edge
	if { $_tabPos != "s" } {
	    $itk_component(canvas) create line \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    [expr {floor($hgt - ($itk_option(-borderwidth)/2.0))}] \
		    [expr {floor($wid - ($itk_option(-borderwidth)/2.0))}] \
		    [expr {floor($hgt - ($itk_option(-borderwidth)/2.0))}] \
		    -width $itk_option(-borderwidth) \
		    -fill [iwidgets::colors::bottomShadow $itk_option(-background)] \
		    -tags BORDER
	} 
	
	# For north, south, and east -- draw the left/west edge
	if { $_tabPos != "w" } {
	    $itk_component(canvas) create line \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    0 \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    $hgt \
		    -width $itk_option(-borderwidth) \
		    -fill [iwidgets::colors::topShadow $itk_option(-background)] \
		    -tags BORDER
	}
	
	# For north, south, and west -- draw the right/east edge
	if { $_tabPos != "e" } {
	    $itk_component(canvas) create line \
		    [expr {floor($wid - ($itk_option(-borderwidth)/2.0))}] \
		    [expr {floor(0 + ($itk_option(-borderwidth)/2.0))}] \
		    [expr {floor($wid - ($itk_option(-borderwidth)/2.0))}] \
		    $hgt \
		    -width $itk_option(-borderwidth) \
		    -fill [iwidgets::colors::bottomShadow $itk_option(-background)] \
		    -tags BORDER
	}
    }
    
}

# -------------------------------------------------------------
# PRIVATE METHOD: _recomputeBorder
#
# Based on current width and height of our canvas, repacks
# the notebook with padding for borderwidth, and calls
# redraw border method 
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_recomputeBorder { } {
    
    set wid [winfo width $itk_component(canvas)]
    set hgt [winfo height $itk_component(canvas)]
    
    _pack $_tabPos
    _redrawBorder $wid $hgt
}

# -------------------------------------------------------------
# PROTECTED METHOD: _pageReconfigure
#
# This method will eventually reconfigure the tab notebook's 
# notebook area to contain the resized child site
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_pageReconfigure { pageName page wid hgt } {
}

# -------------------------------------------------------------
# PRIVATE METHOD: _pack
#
# This method packs the notebook and tabset correctly according
# to the current $tabPos
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_pack { tabPos } {
    
    pack $itk_component(canvas) -fill both -expand yes 
    pack propagate $itk_component(canvas) no
    
    switch $tabPos {
	n {
	    # north
	    pack $itk_component(tabset) \
		    -anchor nw \
		    -fill x \
		    -expand no
	    pack $itk_component(notebook) \
		    -fill both \
		    -expand yes \
		    -padx $itk_option(-borderwidth) \
		    -pady $itk_option(-borderwidth) \
		    -side bottom 
	}
	s {
	    # south
	    pack $itk_component(notebook) \
		    -anchor nw \
		    -fill both \
		    -expand yes \
		    -padx $itk_option(-borderwidth) \
		    -pady $itk_option(-borderwidth)
	    
	    pack $itk_component(tabset) \
		    -side left \
		    -fill x \
		    -expand yes
	}
	w {
	    # west
	    pack $itk_component(tabset) \
		    -anchor nw \
		    -side left \
		    -fill y \
		    -expand no
	    pack $itk_component(notebook) \
		    -anchor nw \
		    -side left \
		    -fill both \
		    -expand yes \
		    -padx $itk_option(-borderwidth) \
		    -pady $itk_option(-borderwidth)
	    
	}
	e {
	    # east
	    pack $itk_component(notebook) \
		    -side left \
		    -anchor nw \
		    -fill both \
		    -expand yes \
		    -padx $itk_option(-borderwidth) \
		    -pady $itk_option(-borderwidth)
	    
	    pack $itk_component(tabset) \
		    -fill y \
		    -expand yes
	}
    }
    
    set wid [winfo width $itk_component(canvas)]
    set hgt [winfo height $itk_component(canvas)]
    
    _redrawBorder $wid $hgt
}



# -------------------------------------------------------------
# PRIVATE METHOD: _resize
#
# This method added by csmith, 5/1/01, to fix a bug with the
# geometry of the tabnotebook.  The hull component's geometry
# was not being updated properly on <Configure> events.
# -------------------------------------------------------------
itcl::body iwidgets::Tabnotebook::_resize {newWidth_ newHeight_} {
  _canvasReconfigure $newWidth_ $newHeight_

  # csmith: 9/14/01 - Commenting out the following code due to
  # SF ticket 461471, which is a dup of the original 452803. Since I
  # can't remember the exact problem surrounding the need to add
  # the _resize method, I'm going to do an undo here, leaving the
  # code for future reference if needed.  Should the original problem
  # arise again I will reinvestigate the need for _resize.
  #
  #  after idle \
  #    "$this component hull configure -width $newWidth_ -height $newHeight_"
}
